<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>斐波那契数列时钟</title>
	</head>
	<style>
		*{
			margin: 0px;
			padding: 0px;
		}
		body{
			background-color: black;
		}
	</style>
	<body>
		<div id="cancas_id" ondblclick="setMarginAlert()">
			<center>
				<canvas id="drawing" width="890" height="590">不支持canvas</canvas>
			</center>
		</div>
	</body>
	<script>
		/**
		 * 钟面上是5个正方形方块，大小有不同，每个方块的边长对应的分别是斐波那契序列的1、1、2、3、5，它们代表的是小时或分钟的数值。
		 * 小时数=红色数值+蓝色数值
		 * 分钟数=(绿色数值+蓝色数值)x5+最外层黄色边框个数
		 *  
		 */
		var drawing = document.getElementById("drawing");
		var ctx = drawing.getContext("2d");
		var fibArr = [1,1,2,3,5];		//实际值
		var indexArr = [0,1,2,3,4];		//下标
		var width = window.innerWidth;//获取窗体宽度
		var high = window.innerHeight;//获取窗体高度
		var comb = new Array();//符合时间值的对象数组
		var _h = 0,_m = 0,_s = 0;	//当前时间
		var m_h = 0,m_m=0; 			//误差调整时间
		var calculateMinute=0;		//斐波那契计算分钟
		var scale = 100;	//比例
		var gap=5;			//间隔大小
		var scaleStart=50;	//起始坐标
		
		self.setInterval("showTime();",200);
		showTime();
		
		var int=self.setInterval("main();",1000);
		main();
		
		function showTime(){
			var time = document.getElementById("time");
			var toDay  = new Date();
			
			_h = toDay.getHours();
			_m = toDay.getMinutes();
			_s = toDay.getSeconds();
			if(_h>12){
				_h = _h-12;
			}
			//time.innerText=dateFormat("HH:MM:SS", toDay);
		}
		
		function main(){
			var hour = new Array();
			var minute = new Array();	
			
			if(m_h != _h || m_m != _m){
				m_h=_h;
				m_m=_m;
				
				hoursMinutesCombination(hour, minute, m_h, m_m);
				//hoursMinutesCombination(hour, minute, 9, 46);
				var res = colorTimeCombination(hour, minute);				
				outFillColor(m_m-calculateMinute);
				//outFillColor(0);

				fillColor(res[Math.floor(Math.random()*res.length)]);
				initCanvas();
			}
		}
		
		function colorTimeCombination(hour, minute){
			var list = new Array();
			var _red = new Array();
			var _blue = new Array();
			var _green = new Array(); 
			for(var i=0; i<hour.length; i++){
				if(minute == null || minute.length<1){
					var timeColor = new Object();
					timeColor.red = new Array();
					timeColor.blue = new Array();
					timeColor.green = new Array();
					var _red = new Array();
					var _blue = new Array();
					var _green = new Array();
										
					for(var t=0; t<hour[i].length; t++){						
						_red.push(hour[i][t]);
					}					
					timeColor.red=_red;
					timeColor.blue=_blue;
					timeColor.green=_green;
					list.push(timeColor);
				}
				
				for(var j=0; j<minute.length; j++){
					var timeColor = new Object();
					timeColor.red = new Array();
					timeColor.blue = new Array();
					timeColor.green = new Array();
					var _red = new Array();
					var _blue = new Array();
					var _green = new Array();
					
					for(var n=0; n<hour[i].length; n++){
						for(var m=0; m<minute[j].length; m++){
							if(hour[i][n]==minute[j][m]) {
								_blue.push(hour[i][n]);
							}
						}
					}
					for(var n=0; n<minute[j].length; n++){
						var isFlag = 1;
						for(var m=0; m<_blue.length; m++){
							if(minute[j][n]==_blue[m]) {
								isFlag = 0;
							}
						}
						if(isFlag==1) {
							_green.push(minute[j][n]);
						}	
					}
					for(var n=0; n<hour[i].length; n++){
						var isFlag = 1;
						for(var m=0; m<_blue.length; m++){
							if(hour[i][n]==_blue[m]) {
								isFlag = 0;
							}
						}
						if(isFlag==1) {
							_red.push(hour[i][n]);
						}	
					}
					timeColor.red=_red;
					timeColor.blue=_blue;
					timeColor.green=_green;
					list.push(timeColor);
				}
			}
			return list;
		}
		
		function hoursMinutesCombination(hour, minute, h, m){
			for(var t=1; t<=5; t++){
				comb = new Array();
				var result = new Array(t);
				combination(0,1,result,t);
				
				for(var i=0; i<comb.length; i++){
					var tim = 0;
					for(var j=0; j<comb[i].length; j++){
						tim += fibArr[comb[i][j]];
					}
					if(tim == h) {//小时
						var _hour = new Array();
						for(var j=0; j<comb[i].length; j++){
							_hour.push(comb[i][j]);
						}
						hour.push(_hour);
					}
					if(m>=tim*5 && m<tim*5+5 && m>4) {//分钟
						calculateMinute=tim*5;
						var _minute = new Array();
						for(var j=0; j<comb[i].length; j++){
							_minute.push(comb[i][j]);
						}
						minute.push(_minute);
					}					
				}
			}
		}
		
		function combination(head, index, arr, k){
			for(var i=head; i<indexArr.length+index-k; i++){
				if (index < k) {
					arr[index - 1] = indexArr[i];		  
					combination(i + 1, index + 1, arr, k);
				} else if (index == k) {
					arr[index - 1] = indexArr[i];
					//System.out.println(arr[0]+"，"+arr[1]);
					//System.out.println(arr[0]+"，"+arr[1]+"，"+arr[2]);
					var list = new Array();
					for(var t=0; t<arr.length; t++) {						
						list.push(arr[t]);
					}
					comb.push(list);
					combination(i + 1, index + 1, arr, k);
				} else {
					return;
				}
			}
		}
		
		function outFillColor(minute){
			ctx.fillStyle  = "white";
			ctx.fillRect(0,0,scaleStart+scale*8+gap*8,scaleStart*2+scale*5-gap*2);
			
			ctx.fillStyle  = "#ffc107";
			if(minute==1){
				ctx.fillRect(scaleStart-gap*2,0,scaleStart+scale*8+gap*2,scaleStart-gap*2);//上
			}else if(minute==2){
				ctx.fillRect(scaleStart-gap*2,0,scaleStart+scale*8+gap*2,scaleStart-gap*2);//上
				ctx.fillRect(scaleStart+scale*8,0,scaleStart,scaleStart*2+scale*5);//右
			}else if(minute==3){
				ctx.fillRect(scaleStart-gap*2,0,scale*8+gap*2,scaleStart);//上
				ctx.fillRect(scaleStart+scale*8,0,scaleStart,scaleStart*2+scale*5);//右
				ctx.fillRect(0,scaleStart+scale*5,scaleStart+scale*8,scaleStart);//下
			}else if(minute==4){
				ctx.fillRect(scaleStart-gap*2,0,scale*8+gap*2,scaleStart);//上
				ctx.fillRect(scaleStart+scale*8,0,scaleStart,scaleStart*2+scale*5);//右
				ctx.fillRect(0,scaleStart+scale*5,scaleStart+scale*8,scaleStart);//下
				ctx.fillRect(0,0,scaleStart,scaleStart+scale*5);//左
			}
		}
		
		function initCanvas(){
			//确定浏览器支持<canvas>元素
			if(drawing.getContext){
				ctx.fillStyle  = "black";
				//竖线
				ctx.fillRect(scaleStart-gap*2,scaleStart-gap*2,gap*2,scale*5+gap*2);
				ctx.fillRect(scaleStart+scale*8-gap*2,scaleStart-gap*2,gap*2,scale*5);
				ctx.fillRect(scale*2+scaleStart-gap*2,scaleStart,gap*2,scale*2-gap*2);
				ctx.fillRect(scale*3+scaleStart-gap*2,scaleStart,gap*2,scale*5-gap*2);
				//横线
				ctx.fillRect(scaleStart-gap*2,scaleStart-gap*2,scale*8,gap*2);
				ctx.fillRect(scaleStart,scaleStart+scale*5-gap*2,scale*8,gap*2);
				ctx.fillRect(scale*2+scaleStart-gap*2,scaleStart+scale-gap*2,scale,gap*2);
				ctx.fillRect(scaleStart,scaleStart+scale*2-gap*2,scale*3,gap*2);
			}
		}
		
		function fillColor(result){
			//console.log(result);
			
			if(drawing.getContext){
				ctx.fillStyle  = "white";
				ctx.fillRect(scaleStart,scaleStart,scale*8,scale*5);
				ctx.fillRect(scaleStart,scaleStart,scale*2,scale*2);			//2-2
				ctx.fillRect(scale*2+scaleStart,scaleStart,scale,scale);		//1-0
				ctx.fillRect(scale*2+scaleStart,scaleStart+scale,scale,scale);	//1-1				
				ctx.fillRect(scaleStart,scale*2+scaleStart,scale*3,scale*3);	//3-3
				ctx.fillRect(scale*3+scaleStart,scaleStart,scale*5,scale*5);	//5-4
				
				if(result.red != null && result.red.length>0){
					ctx.fillStyle  = "red";					
					for(var i=0; i<result.red.length; i++){
						if(result.red[i] == 0){
							ctx.fillRect(scale*2+scaleStart,scaleStart,scale-gap*2,scale-gap*2);		//1-0
						}else if(result.red[i] == 1){
							ctx.fillRect(scale*2+scaleStart,scaleStart+scale,scale-gap*2,scale-gap*2);	//1-1
						}else if(result.red[i] == 2){
							ctx.fillRect(scaleStart,scaleStart,scale*2-gap*2,scale*2-gap*2);			//2-2
						}else if(result.red[i] == 3){
							ctx.fillRect(scaleStart,scale*2+scaleStart,scale*3-gap*2,scale*3-gap*2);	//3-3
						}else if(result.red[i] == 4){
							ctx.fillRect(scale*3+scaleStart,scaleStart,scale*5-gap*2,scale*5-gap*2);	//5-4
						}
					}
				}
				if(result.blue != null && result.blue.length>0){
					ctx.fillStyle  = "blue";					
					for(var i=0; i<result.blue.length; i++){
						if(result.blue[i] == 0){
							ctx.fillRect(scale*2+scaleStart,scaleStart,scale-gap*2,scale-gap*2);		//1-0
						}else if(result.blue[i] == 1){
							ctx.fillRect(scale*2+scaleStart,scaleStart+scale,scale-gap*2,scale-gap*2);	//1-1
						}else if(result.blue[i] == 2){
							ctx.fillRect(scaleStart,scaleStart,scale*2-gap*2,scale*2-gap*2);			//2-2
						}else if(result.blue[i] == 3){
							ctx.fillRect(scaleStart,scale*2+scaleStart,scale*3-gap*2,scale*3-gap*2);	//3-3
						}else if(result.blue[i] == 4){
							ctx.fillRect(scale*3+scaleStart,scaleStart,scale*5-gap*2,scale*5-gap*2);	//5-4
						}
					}
				}
				if(result.green != null && result.green.length>0){
					ctx.fillStyle  = "green";
					for(var i=0; i<result.green.length; i++){
						if(result.green[i] == 0){
							ctx.fillRect(scale*2+scaleStart,scaleStart,scale-gap*2,scale-gap*2);		//1-0
						}else if(result.green[i] == 1){
							ctx.fillRect(scale*2+scaleStart,scaleStart+scale,scale-gap*2,scale-gap*2);	//1-1
						}else if(result.green[i] == 2){
							ctx.fillRect(scaleStart,scaleStart,scale*2-gap*2,scale*2-gap*2);			//2-2
						}else if(result.green[i] == 3){
							ctx.fillRect(scaleStart,scale*2+scaleStart,scale*3-gap*2,scale*3-gap*2);	//3-3
						}else if(result.green[i] == 4){
							ctx.fillRect(scale*3+scaleStart,scaleStart,scale*5-gap*2,scale*5-gap*2);	//5-4
						}
					}
				}				
			}
		}
		
		function dateFormat(fmt, date) {
		    let ret;
		    const opt = {
		        "Y+": date.getFullYear().toString(),        // 年
		        "m+": (date.getMonth() + 1).toString(),     // 月
		        "d+": date.getDate().toString(),            // 日
		        "H+": date.getHours().toString(),           // 时
		        "M+": date.getMinutes().toString(),         // 分
		        "S+": date.getSeconds().toString()          // 秒
		        // 有其他格式化字符需求可以继续添加，必须转化成字符串
		    };
		    for (let k in opt) {
		        ret = new RegExp("(" + k + ")").exec(fmt);
		        if (ret) {
		            fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
		        };
		    };
		    return fmt;
		}
		
		function setMarginAlert(){
			var top = prompt("上边距(数字)", "");
			var cancas_id = document.getElementById("cancas_id");
			cancas_id.style.cssText="margin-top: "+top+"px;";
		}
	</script>
</html>